require 'depac-deployment/environment_configuration'
require 'depac-deployment/helper'
require 'depac-deployment/configure'
require 'depac-common/constants'
require 'depac-common/utils'
require 'yaml'


#Added by CDL to validate if the configured ihs server has been registed on chef server 20141223
def validateRegistedCA(ihsserverIP)
  caDBKey = nil
  if ihsserverIP
     if (File.exists?(Depac::CloudDeploymentConstants::CADB_PWD_REG_FILE_PATH) && (caDBKeyList = YAML.load_file(Depac::CloudDeploymentConstants::CADB_PWD_REG_FILE_PATH)) != nil) 
         #Depac::Log.write("INFO", "CADB PWD List is #{caDBKeyList }")
         if caDBKeyList[ihsserverIP]["pwd"] && File.exists?("ihs_keystore/#{ihsserverIP}/ihsserverkdb.jks")
            caDBKey= caDBKeyList[ihsserverIP]["pwd"]  
         else
            Depac::Log.write("INFO", " can not find ihs_keystore/#{ihsserverIP}/ihsserverkdb.jks or ihsserver ssl pwd is null")        
         end
     else
         Depac::Log.write("INFO", "Can not find : #{Depac::CloudDeploymentConstants::CADB_PWD_REG_FILE_PATH}")
     end
 end 
 return caDBKey
end 

# Added by CDL 20141222 to configure ihs server plugin configure file
# ihsaddress: the target ihsaddress
# private_key_path: point to the SSH private key path
# ipStringForWebServer: 1.11.111.1~2.22.222.2
# action: add/delete add means add app node to plugin; delete means remove app node from plugin;
# environment: ci/dev/prod  used to mark current enviroment 
# enableSSL: true/false  used to mark if need to enable SSL when configure plugin -- just work for add action
def configureIHSPlugin(ihsaddress, private_key_path, ipStringForWebServer,  action, enableSSL)
      #Here we need to upldate all application node to enable SSL
      #if validateRegistedCA(ihsaddress)
           #ipStringForWebServerArray=ipStringForWebServer.split(" ")
           #ipStringForWebServerArray.each do |typeStr|
              #type, value=typeStr.split("=")
              cmdstr = "ssh -t -t -i #{private_key_path} root@#{ihsaddress} -o StrictHostKeyChecking=no 'cd /scripts;./updatePlugin.sh #{ipStringForWebServer} #{action} #{enableSSL}'"
              Depac::Log.write("INFO", "Executing command: " + cmdstr)
              output =  `#{cmdstr}`
              Depac::Log.write("INFO", output)
              Depac::Log.write("INFO", Depac::CloudDeploymentConstants::BORDER_LINE)
          #end 
      #end
end


#This method used to configure SSL on app node
#parameter:
#appserverIP: target app server ip address
#sslPWD: the register ihs server CA database password
#private_key_path: the SSH private key used to connect to target server with no-password
def configureSSL(ihsaddress, appserverIP, sslPWD, private_key_path)
    
        ##{config.scpcmd} -i #{config.wsKeyFile} root@#{vm['ip']}:#{DeplConfig::WS_PUBKEY_LOC_AT_CLI}
        Depac::Log.write("INFO", "copy ssl key database to app server #{appserverIP}.....")
        cmdstr = "scp -o StrictHostKeyChecking=no -i #{private_key_path} ihs_keystore/#{ihsaddress}/ihsserverkdb.jks root@#{appserverIP}:/tmp"
        Depac::Log.write("INFO", "Executing command: " + cmdstr)
        output =  `#{cmdstr}`
        Depac::Log.write("INFO", output)
        Depac::Log.write("INFO", Depac::CloudDeploymentConstants::BORDER_LINE)
                 
        Depac::Log.write("INFO", "enalbe ssl on appserver #{appserverIP}.....")
        #the common out command is old one just can add app node in plugin file
        #cmdstr = "ssh -t -t -i #{private_key_path} root@#{appserverIP} -o StrictHostKeyChecking=no 'cd /migration;./enableSSL.sh #{sslPWD}'"
        cmdstr = "ssh -t -t -i #{private_key_path} root@#{appserverIP} -o StrictHostKeyChecking=no 'cd /migration;./enableSSL.sh #{sslPWD}'"
        Depac::Log.write("INFO", "Executing command: " + cmdstr)
        output =  `#{cmdstr}`
        Depac::Log.write("INFO", output)
        Depac::Log.write("INFO", Depac::CloudDeploymentConstants::BORDER_LINE)
end 

#This method used to update IHSPlugin based on the final output YAML file after createEnvironment/addInstance
#parameter:
#fileName: the final output YAML file path 
def updateIHSPlugin(fileName, path, private_key_path, action)   

   if (path == nil)
	filePath = "#{File.expand_path("~/DeploymentOutput")}"
   else
	filePath = "#{File.expand_path(path)}"
   end 

   fileLocation="#{filePath}/#{fileName}"

   Depac::Log.write("INFO", "input yaml file path is: #{fileLocation}") 

   startConfigureTime = Time.new
  
   if File.exists?(fileLocation)

      envConfig = YAML.load_file(fileLocation) 
 
      nodeInfoMap = Hash.new
      
      typeArr = getEnvironmentTypes()

      #Generate nodeInfoMap object
      typeArr.each do |type|
         if envConfig[type] != nil
                typeNodes=envConfig[type]
                typeNodes.each do |typenode|
                      if typenode["role"] == "appserver"
                             Depac::Log.write("INFO", "start copy nodeinfoArr for type: #{type}") 
                             typenodeInfoArr= Array.new
                             appnodeinfoMap = Hash.new
                             typenodeInfoArr = typenode["node_info"]
                             #nodeInfoMap[type]=typenodeInfoArr 
                             appnodeinfoMap["appserver"]=typenodeInfoArr 
                             nodeInfoMap[type]=appnodeinfoMap
                             Depac::Log.write("INFO", "current app node list is :  #{nodeInfoMap[type]}") 
                      end
                end                
         end
      end          
 

      #GenerateWebServer IP String 
      stringParamForWebserver = getStringParamForWebServer(nodeInfoMap)
    
      Depac::Log.write("INFO", "#{stringParamForWebserver}") 
      
      typeArr = getEnvironmentTypes()
      
      typeArr.each do |type|
         if(nodeInfoMap[type] != nil && nodeInfoMap[type]["appserver"] !=nil)
               nodeInfoArr = nodeInfoMap[type]["appserver"]
               Depac::Log.write("INFO", "Configuring #{type}: appserver on IHS ")
               Depac::Log.write("INFO", Depac::CloudDeploymentConstants::BORDER_LINE)
               
               nodeInfoArr.each do |hostnameIPMap|
                  #Add by CDL 20141222 enable SSL if defined ihserver server  and app server for current type
                  if(envConfig['ihsserver'] != nil  && action != "remove" && envConfig['ihsConfig']['enableSSL'])
                      if (envConfig['ihsserver'][type] !=nil)
                                              
                         ihsaddressArray=envConfig['ihsserver'][type].split(";")
                                           
                         hasConfigured=false
                                           
                         ihsaddressArray.each do |ihsaddress|                                             
                                                                                    
                             Depac::Log.write("INFO", "Configuring appserver #{hostnameIPMap['IP']} to ihs server #{ihsaddress}")                                           
                             Depac::Log.write("INFO", Depac::CloudDeploymentConstants::BORDER_LINE)

                             #call updateWLPServer.sh to update server.xml                    
                             #invoke validateRegistedCA method from depac-deployment\lib\depac-deployment\helper.rb
                                              
                             sslPWD=validateRegistedCA(ihsaddress)
                             Depac::Log.write("INFO", "validateRegistedCA return ssl password is : #{sslPWD}")

                             if sslPWD !=nil && !hasConfigured
                                Depac::Log.write("INFO", "start call new method from update_ihsplugin.rb")
                                configureSSL(ihsaddress, hostnameIPMap['IP'], sslPWD, private_key_path)
                                                    
                                hasConfigured=true
                             end                                             
                          end
                       end
                   end                 
                end 
                
                #Added by CDL 201412191803 to configure IHS server plugin for web application node
                Depac::Log.write("INFO","current type is: #{type} ")
                if(envConfig != nil && envConfig['ihsserver'] != nil)
                       if(envConfig['ihsserver'][type] != nil && stringParamForWebserver!=nil)
                             ihsaddressArray=envConfig['ihsserver'][type].split(";")
                             ihsaddressArray.each do |ihsaddress|
                                 Depac::Log.write("INFO","Configure ihsserver #{ihsaddress} with stringParamForWebServer: #{stringParamForWebserver} ")
                                 #configureIHSPlugin_internal(ihsaddress,stringParamForWebserver ,stringParam ,private_key_path)
               
                                 ipStringForWebServerArray=stringParamForWebserver.split(" ")
                                 ipStringForWebServerArray.each do |type_appIPStr|
                                 type_Template, value=type_appIPStr.split("=")            
                                 if type_Template == type
                                         configureIHSPlugin(ihsaddress, private_key_path, value,  action, envConfig['ihsConfig']['enableSSL'])
                                 end
                             end              
                       end
                else
                     Depac::Log.write("INFO", "Ignore configure IHS plugin for web application.")
                end                                      
          end
       end        
    end
   end 
   endConfigureTime = Time.new
   Depac::Log.write("INFO", "Time taken to configure instances: #{computeDuration(endConfigureTime - startConfigureTime)}")
   Depac::Log.write("INFO", Depac::CloudDeploymentConstants::BORDER_LINE)  
end 

#This method used to update IHSPlugin based on the final output YAML file after createEnvironment/addInstance
#parameter:
#fileName: the final output YAML file path 
def updateIHSPlugin_internal(nodeInfoMap, private_key_path, envConfig, action)   

   startConfigureTime = Time.new
  
   if nodeInfoMap != nil

      #GenerateWebServer IP String 
      stringParamForWebserver = getStringParamForWebServer(nodeInfoMap)
    
      Depac::Log.write("INFO", "#{stringParamForWebserver}") 
      
      typeArr = getEnvironmentTypes()
      
      typeArr.each do |type|
         if(nodeInfoMap[type] != nil && nodeInfoMap[type]["appserver"] !=nil)
               nodeInfoArr = nodeInfoMap[type]["appserver"]
               Depac::Log.write("INFO", "Configuring #{type}: appserver on IHS ")
               Depac::Log.write("INFO", Depac::CloudDeploymentConstants::BORDER_LINE)
               
               nodeInfoArr.each do |hostnameIPMap|
                  #Add by CDL 20141222 enable SSL if defined ihserver server  and app server for current type
                  if(envConfig['ihsserver'] != nil && action != "remove" && envConfig['ihsConfig']['enableSSL'])
                      if (envConfig['ihsserver'][type] !=nil)
                                              
                         ihsaddressArray=envConfig['ihsserver'][type].split(";")
                                           
                         hasConfigured=false
                                           
                         ihsaddressArray.each do |ihsaddress|                                             
                                                                                    
                             Depac::Log.write("INFO", "Configuring appserver #{hostnameIPMap['IP']} on ihs server #{ihsaddress}")                                           
                             Depac::Log.write("INFO", Depac::CloudDeploymentConstants::BORDER_LINE)

                             #call updateWLPServer.sh to update server.xml                    
                             #invoke validateRegistedCA method from depac-deployment\lib\depac-deployment\helper.rb
                                              
                             sslPWD=validateRegistedCA(ihsaddress)
                             Depac::Log.write("INFO", "validateRegistedCA return ssl password is : #{sslPWD}")
                             
                             if action != "remove"
                               if sslPWD !=nil && !hasConfigured
                                 Depac::Log.write("INFO", "start call new method from update_ihsplugin.rb")
                                 configureSSL(ihsaddress, hostnameIPMap['IP'], sslPWD, private_key_path)
                                                    
                                 hasConfigured=true
                               end 
                             end                                            
                          end
                       end
                   end                 
                end 
                
                #Added by CDL 201412191803 to configure IHS server plugin for web application node
                Depac::Log.write("INFO","current type is: #{type} ")
                if(envConfig != nil && envConfig['ihsserver'] != nil)
                       if(envConfig['ihsserver'][type] != nil && stringParamForWebserver!=nil)
                             ihsaddressArray=envConfig['ihsserver'][type].split(";")
                             ihsaddressArray.each do |ihsaddress|
                                 Depac::Log.write("INFO","Configure ihsserver #{ihsaddress} with stringParamForWebServer: #{stringParamForWebserver} ")
                                 #configureIHSPlugin_internal(ihsaddress,stringParamForWebserver ,stringParam ,private_key_path)
               
                                 ipStringForWebServerArray=stringParamForWebserver.split(" ")
                                 ipStringForWebServerArray.each do |type_appIPStr|
                                 type_Template, value=type_appIPStr.split("=")            
                                 if type_Template == type
                                         configureIHSPlugin(ihsaddress, private_key_path, value,  action, envConfig['ihsConfig']['enableSSL'])
                                 end
                             end              
                       end
                else
                     Depac::Log.write("INFO", "Ignore configure IHS plugin for web application.")
                end                                      
          end
       end        
    end
   end 
   endConfigureTime = Time.new
   Depac::Log.write("INFO", "Time taken to configure instances: #{computeDuration(endConfigureTime - startConfigureTime)}")
   Depac::Log.write("INFO", Depac::CloudDeploymentConstants::BORDER_LINE)  
end 

def appNodeToNodeInfoMap(envConfig, type)
      
      nodeInfoMap = Hash.new 
      typeArr = Array.new
      
      if type !=nil 
         typeArr.push(type)
      else
         typeArr = getEnvironmentTypes()
      end        
      
      #Generate nodeInfoMap object
      typeArr.each do |type|
         if envConfig[type] != nil
                typeNodes=envConfig[type]
                typeNodes.each do |typenode|
                      if typenode["role"] == "appserver"
                             #Depac::Log.write("INFO", "start copy nodeinfoArr for type: #{type}") 
                             typenodeInfoArr= Array.new
                             appnodeinfoMap = Hash.new
                             typenodeInfoArr = typenode["node_info"]
                             #nodeInfoMap[type]=typenodeInfoArr 
                             appnodeinfoMap["appserver"]=typenodeInfoArr 
                             nodeInfoMap[type]=appnodeinfoMap
                             #Depac::Log.write("INFO", "current app node list is :  #{nodeInfoMap[type]}") 
                      end
                end                
         end
      end       
      return  nodeInfoMap
end